package com.chianghao.qyt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chianghao.qyt.entity.SysOperationAdminRole;
import com.chianghao.qyt.entity.SysOperationRole;
import com.chianghao.qyt.entity.SysOperationRoleMenu;
import com.chianghao.qyt.i18n.SysOperationLanguage;
import com.chianghao.qyt.mapper.SysOperationAdminRoleMapper;
import com.chianghao.qyt.mapper.SysOperationRoleMapper;
import com.chianghao.qyt.mapper.SysOperationRoleMenuMapper;
import com.chianghao.qyt.service.SysOperationRoleService;
import com.chianghao.frame.core.exception.CHLanguageException;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class SysOperationRoleServiceImpl implements SysOperationRoleService {

    @Resource
    SysOperationRoleMapper sysOperationRoleMapper;

    @Resource
    SysOperationRoleMenuMapper sysOperationRoleMenuMapper;

    @Resource
    SysOperationAdminRoleMapper sysOperationAdminRoleMapper;


    @Override
    public IPage<SysOperationRole> page(Integer pageIndex, Integer pageSize) {
        return sysOperationRoleMapper.selectPage(new Page<SysOperationRole>(pageIndex, pageSize), null);
    }


    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void add(String name, String remark, Set<String> menuIds,Set<String> menuHalfIds) {
        if (StringUtils.isBlank(name)) {
            throw new CHLanguageException(SysOperationLanguage.PARAM_NULL);
        }
        // 生成角色
        SysOperationRole role = new SysOperationRole();
        role.setRoleName(name);
        role.setRemark(remark);
        this.sysOperationRoleMapper.insert(role);
        // 给角色授权
        setRoleMenus(menuIds,menuHalfIds, role.getId());
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void modify(Long id, String name, String remark, Set<String> menuIds,Set<String> menuHalfIds) {
        SysOperationRole role = this.sysOperationRoleMapper.selectById(id);
        if (role == null) {
            throw new CHLanguageException(SysOperationLanguage.ENTITY_NOT_EXIST);
        }
        // 更新角色
        if (StringUtils.isNotEmpty(name) || StringUtils.isNotEmpty(remark)) {
            new LambdaUpdateChainWrapper<SysOperationRole>(this.sysOperationRoleMapper)
                    .eq(SysOperationRole::getId, id)
                    .set(StringUtils.isNotEmpty(name), SysOperationRole::getRoleName, name)
                    .set(StringUtils.isNotEmpty(remark), SysOperationRole::getRoleName, remark)
                    .update();
        }
        // 删除原来的授权
        this.sysOperationRoleMenuMapper.delete(new QueryWrapper<SysOperationRoleMenu>().lambda().eq(SysOperationRoleMenu::getRoleId, id));
        // 设置新的授权
        setRoleMenus(menuIds,menuHalfIds, id);
    }

    @Transactional(rollbackFor = Throwable.class)
    public void setRoleMenus(Set<String> menuIds, Set<String> menuHalfIds,Long roleId) {
        if (menuIds == null || menuIds.isEmpty()) {
            return;
        }
        List<SysOperationRoleMenu> roleMenus = new java.util.ArrayList<>(menuIds.stream().map(i -> {
            SysOperationRoleMenu roleMenu = new SysOperationRoleMenu();
            roleMenu.setMenuId(i);
            roleMenu.setRoleId(roleId);
            roleMenu.setState(1);
            return roleMenu;
        }).toList());

        if(menuHalfIds!=null && !menuHalfIds.isEmpty()){
            for(String id:menuHalfIds) {
                SysOperationRoleMenu roleMenu = new SysOperationRoleMenu();
                roleMenu.setMenuId(id);
                roleMenu.setRoleId(roleId);
                roleMenu.setState(0);
                roleMenus.add(roleMenu);
            }
        }

        this.sysOperationRoleMenuMapper.insertBatch(roleMenus);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void delete(String id) {
        // 删除角色和菜单的对应管理
        this.sysOperationRoleMenuMapper.delete(new QueryWrapper<SysOperationRoleMenu>().lambda().eq(SysOperationRoleMenu::getRoleId,id));
        // 删除角色
        this.sysOperationRoleMapper.deleteById(id);
        // 删除角色对应的账号关系
        this.sysOperationAdminRoleMapper.delete(new QueryWrapper<SysOperationAdminRole>().lambda().eq(SysOperationAdminRole::getRoleId,id));
    }

    @Override
    public Map<Long, Set<SysOperationRoleMenu>> queryRoleToMenuIdsMap(Set<Long> roleIds) {
        if (roleIds == null || roleIds.isEmpty()) {
            return null;
        }
        List<SysOperationRoleMenu> roleMenus = this.sysOperationRoleMenuMapper
                .selectList(
                        new QueryWrapper<SysOperationRoleMenu>().lambda()
                                .in(SysOperationRoleMenu::getRoleId, roleIds));
        return roleMenus.stream().collect(
                Collectors.groupingBy(
                        SysOperationRoleMenu::getRoleId,
                        Collectors.mapping(m->m, Collectors.toCollection(HashSet::new))
                )
        );
    }

    @Override
    public List<SysOperationRole> all() {
        return this.sysOperationRoleMapper.selectList(null);
    }


}
